package com.example.demo.controller;

import com.example.demo.common.Result;
import com.example.demo.dto.UserLoginDto;
import com.example.demo.dto.UserProfileDto;
import com.example.demo.dto.UserRegisterDto;
import com.example.demo.entity.User;
import com.example.demo.entity.UserStats;
import com.example.demo.service.PermissionService;
import com.example.demo.service.UserService;
import com.example.demo.service.UserStatsService;
import com.example.demo.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户控制器
 * 处理用户相关的HTTP请求
 */
@RestController
@RequestMapping("/api/user")
public class UserController {
    
    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    private final UserService userService;
    private final UserStatsService userStatsService;
    private final PermissionService permissionService;
    private final JwtUtil jwtUtil;
    
    /**
     * 构造器注入
     * @param userService 用户服务
     * @param userStatsService 用户统计服务
     * @param permissionService 权限服务
     * @param jwtUtil JWT工具
     */
    public UserController(UserService userService, UserStatsService userStatsService, 
                         PermissionService permissionService, JwtUtil jwtUtil) {
        this.userService = userService;
        this.userStatsService = userStatsService;
        this.permissionService = permissionService;
        this.jwtUtil = jwtUtil;
    }
    
    /**
     * 用户注册接口
     * @param userRegisterDto 注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    public Result<User> register(@Valid @RequestBody UserRegisterDto userRegisterDto) {
        log.info("收到用户注册请求，用户名：{}", userRegisterDto.getUsername());
        
        User user = userService.register(userRegisterDto);
        
        return Result.success("注册成功", user);
    }
    
    /**
     * 用户登录接口
     * @param userLoginDto 登录信息
     * @return 登录结果（包含JWT token）
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@Valid @RequestBody UserLoginDto userLoginDto) {
        log.info("收到用户登录请求，用户名：{}", userLoginDto.getUsername());
        
        try {
            // 验证用户登录
            User user = userService.login(userLoginDto);
            
            // 查询用户角色和权限
            List<String> roleCodes = permissionService.getUserRoleCodes(user.getId());
            List<String> permissionCodes = permissionService.getUserPermissionCodes(user.getId());
            
            log.info("用户{}登录成功，角色：{}，权限数量：{}", user.getUsername(), roleCodes, permissionCodes.size());
            
            // 生成JWT token
            String token = jwtUtil.generateToken(user.getId(), user.getUsername(), roleCodes, permissionCodes);
            String refreshToken = jwtUtil.generateRefreshToken(user.getId(), user.getUsername());
            
            // 构建响应数据
            Map<String, Object> data = new HashMap<>();
            data.put("user", user);
            data.put("token", token);
            data.put("refreshToken", refreshToken);
            data.put("roles", roleCodes);
            data.put("permissions", permissionCodes);
            
            return Result.success("登录成功", data);
            
        } catch (Exception e) {
            log.error("用户登录异常，用户名：{}", userLoginDto.getUsername(), e);
            return Result.error("登录失败：" + e.getMessage());
        }
    }
    
    /**
     * 检查用户名是否存在
     * @param username 用户名
     * @return 检查结果
     */
    @GetMapping("/check-username")
    public Result<Boolean> checkUsername(@RequestParam String username) {
        boolean exists = userService.isUsernameExists(username);
        return Result.success(exists);
    }
    
    /**
     * 检查邮箱是否存在
     * @param email 邮箱
     * @return 检查结果
     */
    @GetMapping("/check-email")
    public Result<Boolean> checkEmail(@RequestParam String email) {
        boolean exists = userService.isEmailExists(email);
        return Result.success(exists);
    }
    
    /**
     * 检查手机号是否存在
     * @param phone 手机号
     * @return 检查结果
     */
    @GetMapping("/check-phone")
    public Result<Boolean> checkPhone(@RequestParam String phone) {
        boolean exists = userService.isPhoneExists(phone);
        return Result.success(exists);
    }
    
    /**
     * 根据ID获取用户信息
     * @param id 用户ID
     * @return 用户信息
     */
    @GetMapping("/{id}")
    public Result<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.success(user);
    }
    
    /**
     * 获取用户个人资料
     * @param id 用户ID
     * @return 用户个人资料
     */
    @GetMapping("/{id}/profile")
    public Result<User> getUserProfile(@PathVariable Long id) {
        log.info("获取用户个人资料，用户ID：{}", id);
        
        User user = userService.getUserById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.success("获取成功", user);
    }
    
    /**
     * 更新用户个人资料
     * @param id 用户ID
     * @param userProfileDto 个人资料信息
     * @return 更新结果
     */
    @PutMapping("/{id}/profile")
    public Result<User> updateUserProfile(@PathVariable Long id, @Valid @RequestBody UserProfileDto userProfileDto) {
        log.info("收到更新用户资料请求，用户ID：{}", id);
        
        User user = userService.updateUserProfile(id, userProfileDto);
        
        return Result.success("个人资料更新成功", user);
    }
    
    /**
     * 检查邮箱是否存在（排除指定用户）
     * @param email 邮箱
     * @param excludeUserId 排除的用户ID
     * @return 检查结果
     */
    @GetMapping("/check-email-exclude")
    public Result<Boolean> checkEmailExcludeUser(@RequestParam String email, @RequestParam Long excludeUserId) {
        boolean exists = userService.isEmailExists(email, excludeUserId);
        return Result.success(exists);
    }
    
    /**
     * 检查手机号是否存在（排除指定用户）
     * @param phone 手机号
     * @param excludeUserId 排除的用户ID
     * @return 检查结果
     */
    @GetMapping("/check-phone-exclude")
    public Result<Boolean> checkPhoneExcludeUser(@RequestParam String phone, @RequestParam Long excludeUserId) {
        boolean exists = userService.isPhoneExists(phone, excludeUserId);
        return Result.success(exists);
    }
    
    /**
     * 获取用户统计信息
     * @param id 用户ID
     * @return 用户统计信息
     */
    @GetMapping("/{id}/stats")
    public Result<Map<String, Object>> getUserStats(@PathVariable Long id) {
        log.info("获取用户统计信息，用户ID：{}", id);
        
        try {
            // 获取统计数据
            UserStats stats = userStatsService.getUserStats(id);
            Long accountAge = userStatsService.calculateAccountAge(id);
            
            // 构建返回数据
            Map<String, Object> result = new HashMap<>();
            result.put("loginCount", stats.getLoginCount() != null ? stats.getLoginCount() : 0);
            result.put("onlineTime", formatOnlineTime(stats.getTotalOnlineTime()));
            result.put("lastLogin", formatLastLogin(stats.getLastLoginTime()));
            result.put("accountAge", accountAge);
            
            return Result.success("获取统计信息成功", result);
            
        } catch (Exception e) {
            log.error("获取用户{}统计信息失败：", id, e);
            
            // 返回默认统计数据
            Map<String, Object> defaultStats = new HashMap<>();
            defaultStats.put("loginCount", 0);
            defaultStats.put("onlineTime", 0);
            defaultStats.put("lastLogin", "今天");
            defaultStats.put("accountAge", 1);
            
            return Result.success("获取统计信息成功", defaultStats);
        }
    }
    
    /**
     * 记录用户登出
     * @param id 用户ID
     * @param onlineMinutes 在线时长（分钟）
     * @return 操作结果
     */
    @PostMapping("/{id}/logout")
    public Result<String> recordLogout(@PathVariable Long id, @RequestParam(required = false) Long onlineMinutes) {
        log.info("记录用户登出，用户ID：{}，在线时长：{}分钟", id, onlineMinutes);
        
        try {
            userStatsService.recordLogout(id, onlineMinutes);
            return Result.success("登出记录成功");
        } catch (Exception e) {
            log.error("记录用户{}登出失败：", id, e);
            return Result.error("记录登出失败");
        }
    }
    
    /**
     * 格式化在线时长
     * @param totalMinutes 总分钟数
     * @return 格式化后的时长
     */
    private Object formatOnlineTime(Long totalMinutes) {
        if (totalMinutes == null || totalMinutes == 0) {
            return 0;
        }
        
        // 转换为小时，保留一位小数
        double hours = totalMinutes / 60.0;
        return Math.round(hours * 10.0) / 10.0;
    }
    
    /**
     * 格式化最后登录时间
     * @param lastLoginTime 最后登录时间
     * @return 格式化后的时间描述
     */
    private String formatLastLogin(LocalDateTime lastLoginTime) {
        if (lastLoginTime == null) {
            return "未知";
        }
        
        LocalDateTime now = LocalDateTime.now();
        long minutesDiff = ChronoUnit.MINUTES.between(lastLoginTime, now);
        long hoursDiff = ChronoUnit.HOURS.between(lastLoginTime, now);
        long daysDiff = ChronoUnit.DAYS.between(lastLoginTime, now);
        
        if (minutesDiff < 60) {
            return minutesDiff <= 1 ? "刚刚" : minutesDiff + "分钟前";
        } else if (hoursDiff < 24) {
            return hoursDiff + "小时前";
        } else if (daysDiff == 1) {
            return "昨天";
        } else if (daysDiff < 7) {
            return daysDiff + "天前";
        } else {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM月dd日");
            return lastLoginTime.format(formatter);
        }
    }
}
